#include "MessageDispatcher.hpp"
#include "MMessage.hpp"
#include "SceneManager.hpp"
#include "Entities/BaseEntity.hpp"
#include <assert.h>

MessageDispatcher* MessageDispatcher::m_pInstance = 0;

void MessageDispatcher::createInstance()
{
	if(!m_pInstance)
		m_pInstance = new MessageDispatcher();
}

void MessageDispatcher::destroyInstance()
{
	delete m_pInstance;
	m_pInstance = NULL;
}

MessageDispatcher* MessageDispatcher::getInstance()
{
	assert(m_pInstance);

	return m_pInstance;
}

void MessageDispatcher::dispatchMessage(MMessage* pMsg, int senderID, int receiverID)
{
	if(pMsg->getDelay() > 0)
	{
		m_delayedMessages.push_back(pMsg);
		//TODO: sort delayed messages so last one in vector will have shortest delay.
	}
	else
	{
		deliverMessage(pMsg, receiverID);
		//delete pMsg;
	}
}

void MessageDispatcher::deliverMessage(MMessage *pMsg, int receiverID)
{
	BaseEntity* pTargetEntity = SceneManager::GetInstance()->GetEntityByID(receiverID);
	pTargetEntity->handleMessage(pMsg);
}

void  MessageDispatcher::update(clock_t tick)
{
	//I don't like the way it looks and works. Better solution needed.

	std::vector<MMessage*>::iterator currentMessage = m_delayedMessages.begin();

	for(currentMessage; currentMessage != m_delayedMessages.end(); ++currentMessage)
		(*currentMessage)->modifyDelay(-tick);


	bool bInspectMessages = true;

	while(bInspectMessages)
	{
		currentMessage = m_delayedMessages.begin();
		bInspectMessages = false;

		for(currentMessage; currentMessage != m_delayedMessages.end(); ++currentMessage)
		{
			if((*currentMessage)->getDelay() <= 0)
			{
				deliverMessage((*currentMessage), (*currentMessage)->getAddressee());
				currentMessage = m_delayedMessages.erase(currentMessage);

				bInspectMessages = true;
			}
		}
	}
}

//EOF
